package com.lich.util;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Workbook;

/**
 * @author luosf
 *
 * @param <T>
 */
public class ExcelUtil<T> {
	
	private Map<String, CellStyle> styles;
    /**
     * 导出报表 excelHeader表头的长度，不能大于colunms字段数
     * @param list 数据集
     * @param cls 类名
     * @param excelHeader 表头
     * @param colunms 需要的字段 
     * @param response 
     * @param fileName 文件名
     * @return
     * @throws IOException 
     */
    public HSSFWorkbook export(List<T> list,Class<?> cls, String[] excelHeader,String[] colunms, HttpServletResponse response, String fileName) throws IOException {    
        if(excelHeader.length > colunms.length){
        	//表头的长度，不能大于字段数
        	return null;
        }
    	HSSFWorkbook wb = new HSSFWorkbook(); 
    	styles = createStyles(wb);
        HSSFSheet sheet = wb.createSheet();  
        HSSFRow row = sheet.createRow((int) 0);    
        HSSFCellStyle style = wb.createCellStyle(); 
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);    
        for (int i = 0; i < excelHeader.length; i++) {    
            HSSFCell cell = row.createCell(i);    
            cell.setCellValue(excelHeader[i]);    
            cell.setCellStyle(styles.get("header"));
            sheet.setColumnWidth(i,256*15);
        }
        Field[] fs = cls.getDeclaredFields();
        cls.getTypeParameters().getClass();
        for (int i = 0; i < list.size(); i++) {    
            row = sheet.createRow(i + 1);    
            T t = list.get(i);   
            for (int j = 0 ; j<excelHeader.length ; j++) {
            	for (Field field : fs) {
					String name = field.getName();
					if(name.equalsIgnoreCase(colunms[j])){
						Type type = field.getGenericType();
						Object obj = ReflectionUtil.invokeGetterMethod(t, name);
						setCellValue(row,type,obj,j);
					}
				}
			}
        }
        response.setContentType("application/vnd.ms-excel"); 
        System.out.println(fileName);
        response.setHeader("Content-disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"), "ISO8859-1")+".xls");    
        OutputStream ouputStream = response.getOutputStream();    
        wb.write(ouputStream);    
        ouputStream.flush();    
        ouputStream.close();   
        return wb;    
    }

	/** 设置单元格数据
	 * @param row 行对象
	 * @param type 转换类型
	 * @param obj 数据
	 * @param j 单元格列
	 */
	private void setCellValue(HSSFRow row, Type type, Object obj,int j) {
		if(obj == null) return;
		if(type == String.class){
			row.createCell(j).setCellValue((String)obj);
		}else if(type == Integer.class){
			row.createCell(j).setCellValue((Integer)obj);
		}else if(type == Date.class){
			DateFormat date = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
			row.createCell(j).setCellValue(date.format(obj));
		}else if(type == Long.class){
			row.createCell(j).setCellValue((Long)obj);
		}else{
			row.createCell(j).setCellValue("");
		}
		
	}    
	
	/**
	 * 创建表格样式
	 * @param wb 工作薄对象
	 * @return 样式列表
	 */
	private Map<String, CellStyle> createStyles(Workbook wb) {
		Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
		
		CellStyle style = wb.createCellStyle();
		style.setAlignment(CellStyle.ALIGN_CENTER);
		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		Font titleFont = wb.createFont();
		titleFont.setFontName("Arial");
		titleFont.setFontHeightInPoints((short) 16);
		titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		style.setFont(titleFont);
		styles.put("title", style);

		style = wb.createCellStyle();
		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		style.setBorderRight(CellStyle.BORDER_THIN);
		style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setBorderTop(CellStyle.BORDER_THIN);
		style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setBorderBottom(CellStyle.BORDER_THIN);
		style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		Font dataFont = wb.createFont();
		dataFont.setFontName("Arial");
		dataFont.setFontHeightInPoints((short) 10);
		style.setFont(dataFont);
		styles.put("data", style);
		
		style = wb.createCellStyle();
		style.cloneStyleFrom(styles.get("data"));
		style.setAlignment(CellStyle.ALIGN_LEFT);
		styles.put("data1", style);

		style = wb.createCellStyle();
		style.cloneStyleFrom(styles.get("data"));
		style.setAlignment(CellStyle.ALIGN_CENTER);
		styles.put("data2", style);

		style = wb.createCellStyle();
		style.cloneStyleFrom(styles.get("data"));
		style.setAlignment(CellStyle.ALIGN_RIGHT);
		styles.put("data3", style);
		
		style = wb.createCellStyle();
		style.cloneStyleFrom(styles.get("data"));
//		style.setWrapText(true);
		style.setAlignment(CellStyle.ALIGN_CENTER);
		style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setFillPattern(CellStyle.SOLID_FOREGROUND);
		Font headerFont = wb.createFont();
		headerFont.setFontName("Arial");
		headerFont.setFontHeightInPoints((short) 10);
		headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		headerFont.setColor(IndexedColors.WHITE.getIndex());
		style.setFont(headerFont);
		styles.put("header", style);
		
		return styles;
	}
}
